package common

import (
	"adminserver/utils/array_kit"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"math/rand"
	"reflect"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"

	uuid "github.com/satori/go.uuid"
)

type Map map[string]interface{}

var (
	listOfMapItoMapStrErr = "函数ListOfMapIToMapString 数据类型强转失败"
)

//[]map[interface{}]interface{} -> []map[string]string
func ListOfMapIToMapString(ret interface{}) (listOfMap []map[string]string) {
	sucess := InterfaceIsNil(ret)
	if sucess {
		return
	}
	retDataList, ok := ret.([]interface{})
	if !ok {
		panic(listOfMapItoMapStrErr)
	}
	for _, retData := range retDataList {
		dataMap, ok := retData.(map[interface{}]interface{})
		if !ok {
			panic(listOfMapItoMapStrErr)
		}
		tempMap := make(map[string]string)
		for key, val := range dataMap {
			tempKey, ok := key.(string)
			if !ok {
				panic(listOfMapItoMapStrErr)
			}
			tempVal, ok := val.(string)
			if !ok {
				panic(listOfMapItoMapStrErr)
			}
			tempMap[tempKey] = tempVal
			listOfMap = append(listOfMap, tempMap)
		}
	}
	sucess = true
	return
}

func InterfaceIsNil(val interface{}) (flag bool) {
	if !reflect.ValueOf(val).IsValid() {
		return true
	}
	if IsReferenceType(reflect.ValueOf(val)) && reflect.ValueOf(val).IsNil() {
		return true
	}
	return
}

func IsReferenceType(value reflect.Value) bool {
	switch value.Kind() {
	case reflect.Ptr, reflect.Chan, reflect.Interface, reflect.Func, reflect.Map, reflect.Slice:
		return true
	default:
		return false
	}
}

func GetConsecutiveArray(start, end, step int) []int {
	result := []int{}
	for i := start; i <= end; i += step {
		result = append(result, i)
	}
	return result
}

func GetRandomNum(minmum, maximum int) (result int, err error) {
	if maximum-minmum <= 0 {
		return 0, errors.New("maximum must larger than minimum")
	}
	rand.Seed(time.Now().UnixNano())
	return rand.Intn(maximum-minmum) + minmum, nil
}

func GetUUID() string {
	uuid := uuid.NewV4()
	return uuid.String()
}

func GenerateMd5(data []byte) string {
	md5_ := md5.New()
	md5_.Write(data)
	return hex.EncodeToString(md5_.Sum(nil))
}

func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

func Md5Times(str string, count int) string {
	temp := ""
	for i := 0; i < count; i++ {
		temp = Md5(str)
	}
	return temp
}

func InterfaceKeyToStringKey(imap map[interface{}]interface{}) map[string]interface{} {
	result := map[string]interface{}{}
	for ikey, ivalue := range imap {
		if stringKey, ok := ikey.(string); ok {
			result[stringKey] = ivalue
		}
	}
	return result
}

//StructConvertToMap Converting struct type to map type
func StructConvertToMap(struct_ interface{}, fieldNamePrefixToTrim string, isCaseSensitive bool) (result map[interface{}]interface{}, err error) { //key:field name.  value:value of struct field
	st_v := reflect.Indirect(reflect.ValueOf(struct_))
	if !st_v.IsValid() || (IsReferenceType(st_v) && st_v.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	if st_v.Kind() == reflect.Interface {
		st_v = st_v.Elem()
	}
	if st_v.Kind() != reflect.Struct {
		return nil, errors.New("type is not struct")
	}
	result = make(map[interface{}]interface{}, 0)
	for i := 0; i < st_v.NumField(); i++ {
		fieldName := strings.TrimPrefix(st_v.Type().Field(i).Name, fieldNamePrefixToTrim)
		if !isCaseSensitive {
			fieldName = strings.ToLower(fieldName)
		}
		result[fieldName] = st_v.Field(i).Interface()
	}
	return result, nil
}

//StructConvertToMap Converting struct type to map type
func StructConvertToMap2(struct_ interface{}, fieldNamePrefixToTrim string, isCaseSensitive bool) (result map[string]interface{}, err error) { //key:field name.  value:value of struct field
	st_v := reflect.Indirect(reflect.ValueOf(struct_))
	if !st_v.IsValid() || (IsReferenceType(st_v) && st_v.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	if st_v.Kind() == reflect.Interface {
		st_v = st_v.Elem()
	}
	if st_v.Kind() != reflect.Struct {
		return nil, errors.New("type is not struct")
	}
	result = make(map[string]interface{}, 0)
	for i := 0; i < st_v.NumField(); i++ {
		fieldName := strings.TrimPrefix(st_v.Type().Field(i).Name, fieldNamePrefixToTrim)
		if !isCaseSensitive {
			fieldName = strings.ToLower(fieldName)
		}
		result[fieldName] = st_v.Field(i).Interface()
	}
	return result, nil
}

//StructConvertToMap Converting struct type to map type
func StructConvertToMap3(structArray_ interface{}, fieldNamePrefixToTrim string, isCaseSensitive bool) (result []map[string]interface{}, err error) { //key:field name.  value:value of struct field
	st_v := reflect.Indirect(reflect.ValueOf(structArray_))
	if !st_v.IsValid() || (IsReferenceType(st_v) && st_v.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	if st_v.Kind() != reflect.Slice && st_v.Kind() != reflect.Array {
		return nil, errors.New("type is not array")
	}
	result = []map[string]interface{}{}
	if st_v.Len() == 0 {
		return result, nil
	}
	if reflect.Indirect(reflect.ValueOf(st_v.Index(0).Interface())).Kind() != reflect.Struct {
		return nil, fmt.Errorf("type of element should be struct")
	}
	for i := 0; i < st_v.Len(); i++ {
		temp, err := StructConvertToMap2(st_v.Index(i).Interface(), fieldNamePrefixToTrim, isCaseSensitive)
		if err != nil {
			return nil, err
		}
		result = append(result, temp)
	}
	return result, nil
}

//GetStructFieldValue Fetching struct field value
func GetStructFieldValue(structObj interface{}, fields ...string) (map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(structObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if objV.Kind() != reflect.Struct {
		return nil, errors.New("structObj type is not correct.only strcut allowed")
	}
	result := make(map[interface{}]interface{}, 0)
	if fields == nil || len(fields) == 0 {
		for i := 0; i < objV.NumField(); i++ {
			if objV.Field(i).CanInterface() {
				result[objV.Type().Field(i).Name] = objV.Field(i).Interface()
			}
		}
		return result, nil
	}
	for _, fieldName := range fields {
		field_v := objV.FieldByName(fieldName)
		if field_v.IsValid() && field_v.CanInterface() {
			result[fieldName] = field_v.Interface()
		}
	}
	return result, nil
}

//GetMapFieldValue Fetching value of map's key and map's value
func GetMapFieldValue(mapObj interface{}, fields ...string) (map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(mapObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if objV.Kind() != reflect.Map {
		return nil, errors.New("mapObj type is not correct.only map allowed")
	}
	result := make(map[interface{}]interface{}, 0)
	if fields == nil || len(fields) == 0 {
		for _, mapKey := range objV.MapKeys() {
			result[mapKey.Interface()] = objV.MapIndex(mapKey).Interface()
		}
		return result, nil
	}
	for _, mapKey := range objV.MapKeys() {
		isExist, _ := array_kit.IsElementInArray(mapKey.Interface(), fields)
		if isExist {
			result[mapKey.Interface()] = objV.MapIndex(mapKey).Interface()
		}
	}
	return result, nil
}

//GetMapFieldValue Fetching value of map's key and map's value
func GetMapIFieldValue(mapObj interface{}, fields ...interface{}) (map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(mapObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if objV.Kind() != reflect.Map {
		return nil, errors.New("mapObj type is not correct.only map allowed")
	}
	result := make(map[interface{}]interface{}, 0)
	if fields == nil || len(fields) == 0 {
		for _, mapKey := range objV.MapKeys() {
			result[mapKey.Interface()] = objV.MapIndex(mapKey).Interface()
		}
		return result, nil
	}
	for _, mapKey := range objV.MapKeys() {
		isExist, _ := array_kit.IsElementInArray(mapKey.Interface(), fields)
		if isExist {
			result[mapKey.Interface()] = objV.MapIndex(mapKey).Interface()
		}
	}
	return result, nil
}

//GetMapFieldValue Fetching value of map's key and map's value
func GetMapStrFieldValue(mapObj interface{}, fields ...string) (map[string]interface{}, error) {
	objV := reflect.ValueOf(mapObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if objV.Kind() != reflect.Map {
		return nil, errors.New("mapObj type is not correct.only map allowed")
	}
	if len(objV.MapKeys()) > 0 && reflect.ValueOf(objV.MapKeys()[0].Interface()).Kind() != reflect.String {
		return nil, errors.New("key of mapObj is not string type")
	}
	result := make(map[string]interface{}, 0)
	for _, mapKey := range objV.MapKeys() {
		if fields == nil || len(fields) == 0 {
			result[reflect.ValueOf(mapKey.Interface()).String()] = objV.MapIndex(mapKey).Interface()
			continue
		}
		isExist, _ := array_kit.IsElementInArray(mapKey.Interface(), fields)
		if isExist {
			result[reflect.ValueOf(mapKey.Interface()).String()] = objV.MapIndex(mapKey).Interface()
		}
	}
	return result, nil
}

//GetMapFieldValue Fetching value of map's key and map's value
func GetMapStrFieldValue2(mapObj interface{}, isCaseSensitive bool, fields ...string) (map[string]interface{}, error) {
	result, err := GetMapStrFieldValue(mapObj, fields...)
	if result == nil {
		return nil, err
	}
	if isCaseSensitive {
		return result, nil
	}
	temp := map[string]interface{}{}
	for key, value := range result {
		temp[strings.ToLower(key)] = value
	}
	return temp, nil
}

func GetFieldValue(originalData interface{}, fields ...string) (map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(originalData)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	switch objV.Kind() {
	case reflect.Map:
		return GetMapFieldValue(originalData, fields...)
	case reflect.Struct:
		return GetStructFieldValue(originalData, fields...)
	}
	return nil, errors.New("Type of originalData is not supported")
}

func GetStrFieldValue(originalData interface{}, fields ...string) (map[string]interface{}, error) {
	objV := reflect.ValueOf(originalData)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return map[string]interface{}{}, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	var err error
	var mapObj interface{}
	switch objV.Kind() {
	case reflect.Map:
		mapObj, err = GetMapFieldValue(originalData, fields...)
	case reflect.Struct:
		mapObj, err = GetStructFieldValue(originalData, fields...)
	}
	if err == nil {
		return GetMapStrFieldValue(mapObj, fields...)
	}
	return map[string]interface{}{}, errors.New("Type of originalData is not supported")
}

func GetStrFieldValueWithCaseCheck(originalData interface{}, isCaseSensitive bool, fields ...string) (map[string]interface{}, error) {
	objV := reflect.ValueOf(originalData)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	result, err := GetStrFieldValue(originalData, fields...)
	if err != nil {
		return nil, err
	}
	if isCaseSensitive {
		return result, nil
	}
	temp := map[string]interface{}{}
	for key, value := range result {
		temp[strings.ToLower(key)] = value
	}
	return temp, nil
}

//GetArray_MapElementFieldValue Fetching value:type is array and element type of array is map
func GetArrayMapElementFieldValue(arrayObjMapElementObj interface{}, fields ...string) ([]map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(arrayObjMapElementObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	result := make([]map[interface{}]interface{}, 0)
	if !(objV.Kind() == reflect.Array || objV.Kind() == reflect.Slice) {
		return nil, errors.New("Type of arrayObjMapElementObj is not correct")
	}
	if objV.Len() > 0 {
		if reflect.ValueOf(objV.Index(0).Interface()).Kind() != reflect.Map {
			return nil, errors.New("Type of arrayObjMapElementObj is not correct")
		}
	} else {
		return result, nil
	}
	for i := 0; i < objV.Len(); i++ {
		tempMap, err := GetMapFieldValue(objV.Index(i).Interface(), fields...)
		if err == nil {
			result = append(result, tempMap)
			continue
		}
		return nil, errors.New("Getting Exception")
	}
	return result, nil
}

//GetArray_MapElementFieldValue Fetching value:type is array and element type of array is map
func GetArrayMapElementStrFieldValue(arrayObjMapElementObj interface{}, fields ...string) ([]map[string]interface{}, error) {
	objV := reflect.ValueOf(arrayObjMapElementObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	result := make([]map[string]interface{}, 0)
	if !(objV.Kind() == reflect.Array || objV.Kind() == reflect.Slice) {
		return nil, errors.New("Type of arrayObjMapElementObj is not correct")
	}
	if objV.Len() > 0 {
		if reflect.ValueOf(objV.Index(0).Interface()).Kind() != reflect.Map {
			return nil, errors.New("Type of arrayObjMapElementObj is not correct")
		}
	} else {
		return result, nil
	}
	for i := 0; i < objV.Len(); i++ {
		tempMap, err := GetMapStrFieldValue(objV.Index(i).Interface(), fields...)
		if err == nil {
			result = append(result, tempMap)
			continue
		}
		return nil, errors.New("Getting Exception")
	}
	return result, nil
}

//GetArrayStructElementFieldValue Fetching value:type is array and element type of array is struct or struct pointer
func GetArrayStructElementFieldValue(structArrayObj interface{}, fields ...string) ([]map[interface{}]interface{}, error) {
	objV := reflect.ValueOf(structArrayObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if !(objV.Kind() == reflect.Array || objV.Kind() == reflect.Slice) {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	elementkind := objV.Type().Elem().Kind()
	if elementkind == reflect.Ptr {
		if objV.Type().Elem().Elem().Kind() != reflect.Struct {
			return nil, errors.New("Type of structArrayObj is not correct")
		}
		elementkind = objV.Type().Elem().Elem().Kind()
	}
	if !(elementkind == reflect.Struct || elementkind == reflect.Interface) {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	result := make([]map[interface{}]interface{}, 0)
	for i := 0; i < objV.Len(); i++ {
		fieldsValue, err := GetStructFieldValue(objV.Index(i).Interface(), fields...)
		if err == nil {
			result = append(result, fieldsValue)
			continue
		}
		return nil, err
	}
	return result, nil
}

//GetArrayStructElementFieldValue Fetching value:type is array and element type of array is struct or struct pointer
func GetArrayStructElementStrFieldValue(structArrayObj interface{}, fields ...string) ([]map[string]interface{}, error) {
	objV := reflect.ValueOf(structArrayObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if !(objV.Kind() == reflect.Array || objV.Kind() == reflect.Slice) {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	elementkind := objV.Type().Elem().Kind()
	if elementkind == reflect.Ptr {
		if objV.Type().Elem().Elem().Kind() != reflect.Struct {
			return nil, errors.New("Type of structArrayObj is not correct")
		}
		elementkind = objV.Type().Elem().Elem().Kind()
	}
	if !(elementkind == reflect.Struct || elementkind == reflect.Interface) {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	result := make([]map[string]interface{}, 0)
	for i := 0; i < objV.Len(); i++ {
		fieldsValue, err := GetStrFieldValue(objV.Index(i).Interface(), fields...)
		if err == nil {
			result = append(result, fieldsValue)
			continue
		}
		return nil, err
	}
	return result, nil
}

//GetArrayStructElementFieldValue Fetching value:type is array and element type of array is struct or struct pointer
func GetArrayStOrMapElementStrFieldValue(arrayObj interface{}, fields ...string) ([]map[string]interface{}, error) {
	objV := reflect.ValueOf(arrayObj)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() == reflect.Interface {
		objV = objV.Elem()
	}
	if !(objV.Kind() == reflect.Array || objV.Kind() == reflect.Slice) {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	elementkind := objV.Type().Elem().Kind()
	isStructElement := false
	switch elementkind {
	case reflect.Struct:
		isStructElement = true
	case reflect.Ptr:
		if objV.Type().Elem().Elem().Kind() == reflect.Struct {
			isStructElement = true
		}
	case reflect.Interface:
		if objV.Len() > 0 && reflect.ValueOf(objV.Index(0).Interface()).Kind() == reflect.Struct {
			isStructElement = true
		}
	}
	if isStructElement {
		return GetArrayStructElementStrFieldValue(arrayObj, fields...)
	}
	return GetArrayMapElementStrFieldValue(arrayObj, fields...)
}

//ArrayStructElementToArrayMap Fetching value:type is array and element type of array is struct or struct pointer
func ArrayStructElementToArrayMap(arrayStruct interface{}, isCaseSensitive bool) ([]map[string]interface{}, error) {
	arrayV := reflect.ValueOf(arrayStruct)
	if !arrayV.IsValid() || (IsReferenceType(arrayV) && arrayV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	arrayV = reflect.Indirect(arrayV)
	if arrayV.Kind() == reflect.Interface {
		arrayV = arrayV.Elem()
	}
	if !(arrayV.Kind() == reflect.Array || arrayV.Kind() == reflect.Slice) {
		return nil, errors.New("type is not correct")
	}
	result := make([]map[string]interface{}, 0)
	if arrayV.Len() == 0 {
		return result, nil
	}
	elementkind := arrayV.Type().Elem().Kind()
	if elementkind == reflect.Ptr {
		if arrayV.Type().Elem().Elem().Kind() != reflect.Struct {
			return nil, errors.New("Type of structArrayObj is not correct")
		}
		elementkind = arrayV.Type().Elem().Elem().Kind()
	}
	if reflect.Indirect(reflect.ValueOf(arrayV.Index(0).Interface())).Kind() != reflect.Struct {
		return nil, errors.New("Type of structArrayObj is not correct")
	}
	for i := 0; i < arrayV.Len(); i++ {
		struct_v := reflect.Indirect(arrayV.Index(i))
		struct_t := reflect.TypeOf(struct_v.Interface())
		temp := make(map[string]interface{}, 0)
		for j := 0; j < struct_v.NumField(); j++ {
			if !isCaseSensitive {
				temp[strings.ToLower(struct_t.Field(j).Name)] = struct_v.Field(j).Interface()
				continue
			}
			temp[struct_t.Field(j).Name] = struct_v.Field(j).Interface()
		}
		result = append(result, temp)
	}
	return result, nil
}

func CaseInSensitiveMap(originalMap interface{}) (map[string]interface{}, error) {
	objV := reflect.ValueOf(originalMap)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() != reflect.Map {
		return nil, errors.New("Type is not correct")
	}
	isKeyInterface := false
	if objV.Type().Key().Kind() == reflect.Interface {
		isKeyInterface = true
		if len(objV.MapKeys()) > 0 && reflect.ValueOf(objV.MapKeys()[0].Interface()).Kind() != reflect.String {
			return nil, errors.New("Map key type is not string")
		}
	} else {
		if objV.Type().Key().Kind() != reflect.String {
			return nil, errors.New("Map key type is not string")
		}
	}
	result := make(map[string]interface{}, 0)
	for _, key := range objV.MapKeys() {
		keyName := ""
		switch isKeyInterface {
		case true:
			keyName = key.Elem().String()
		default:
			keyName = key.String()
		}
		result[strings.ToLower(keyName)] = objV.MapIndex(key).Interface()
	}
	return result, nil
}

func ArrayMapCaseInSensitive(originalMap interface{}) ([]map[string]interface{}, error) {
	objV := reflect.ValueOf(originalMap)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	objV = reflect.Indirect(objV)
	if objV.Kind() != reflect.Slice && objV.Kind() != reflect.Array {
		return nil, errors.New("Type is not correct")
	}
	if objV.Type().Elem().Kind() != reflect.Map {
		return nil, errors.New("Array Element is not map type")
	}
	result := make([]map[string]interface{}, 0)
	for i := 0; i < objV.Len(); i++ {
		tempResult, err := CaseInSensitiveMap(objV.Index(i).Interface())
		if err == nil {
			result = append(result, tempResult)
			continue
		}
		return nil, err
	}
	return result, nil
}

func RecoveryEntityFieldValue(structOrMapObj interface{}, fieldValue interface{}, fieldkey interface{}) error {
	if InterfaceIsNil(structOrMapObj) {
		return fmt.Errorf("structOrMapObj is null")
	}
	objV := reflect.ValueOf(structOrMapObj)
	if objV.Type().Kind() == reflect.Ptr {
		if objV.Type().Elem().Kind() != reflect.Struct && objV.Type().Elem().Kind() != reflect.Map {
			return fmt.Errorf("structOrMapObj should be pointer type")
		}
		objV = objV.Elem()
	}
	if reflect.TypeOf(structOrMapObj).Kind() != reflect.Ptr && reflect.TypeOf(structOrMapObj).Kind() != reflect.Map {
		return fmt.Errorf("structOrMapObj should be pointer to struct or map")
	}
	switch objV.Kind() {
	case reflect.Map:
		objV.SetMapIndex(reflect.ValueOf(fieldkey), reflect.ValueOf(fieldValue))
	case reflect.Struct:
		fieldName, isOk := fieldkey.(string)
		if !isOk {
			return fmt.Errorf("fieldKey of struct should be string type")
		}
		fieldV := objV.FieldByName(fieldName)
		if !fieldV.IsValid() {
			return fmt.Errorf("no field found corresponding to fieldkey in struct object")
		}
		if !fieldV.CanSet() {
			return fmt.Errorf("fieldKey can't be setted.struct obj should be pointer type")
		}
		fieldV.Set(reflect.ValueOf(fieldValue))
	default:
		return fmt.Errorf("type is not be supported")
	}
	return nil
}

func GetEntityFuncByName(obj interface{}, funcName string) (method interface{}, err error) {
	if InterfaceIsNil(obj) {
		return nil, fmt.Errorf("obj is null")
	}
	objV := reflect.ValueOf(obj)
	methodV := objV.MethodByName(funcName)
	if !methodV.IsValid() {
		return nil, fmt.Errorf("target method is found")
	}
	return methodV.Interface(), nil
}

func RecoveryMoreEntityFieldValue(structOrMapObj interface{}, fieldKeyValuePair map[interface{}]interface{}) error {
	if fieldKeyValuePair == nil {
		return fmt.Errorf("fieldKeyValuePair is null")
	}
	for fieldKey, fieldValue := range fieldKeyValuePair {
		err := RecoveryEntityFieldValue(structOrMapObj, fieldValue, fieldKey)
		if err != nil {
			return err
		}
	}
	return nil
}

func MapConvertToStrcut(mapObj interface{}, structObj interface{}, isRecursion bool) (converted interface{}, err error) {
	if InterfaceIsNil(mapObj) {
		return nil, fmt.Errorf("mapObj is null")
	}
	if reflect.Indirect(reflect.ValueOf(mapObj)).Kind() != reflect.Map {
		return nil, fmt.Errorf("mapObj is not map type")
	}
	if len(reflect.Indirect(reflect.ValueOf(mapObj)).MapKeys()) == 0 {
		return nil, fmt.Errorf("mapObj length should be greater than zero")
	}
	if reflect.ValueOf(reflect.Indirect(reflect.ValueOf(mapObj)).MapKeys()[0].Interface()).Kind() != reflect.String {
		return nil, fmt.Errorf("key of mapObj should be string type")
	}
	isPointer := false
	if reflect.TypeOf(structObj).Kind() == reflect.Ptr {
		if reflect.TypeOf(structObj).Elem().Kind() != reflect.Struct {
			return nil, fmt.Errorf("structObj should be struct or pointer to struct")
		}
		isPointer = true
	}
	if !isPointer && reflect.TypeOf(structObj).Kind() != reflect.Struct {
		return nil, fmt.Errorf("structObj should be struct or pointer to struct")
	}
	var tempStruct reflect.Value
	switch isPointer {
	case false:
		tempStruct = reflect.New(reflect.TypeOf(structObj)).Elem()
	default:
		tempStruct = reflect.New(reflect.TypeOf(structObj).Elem()).Elem()
	}
	mapObjV := reflect.ValueOf(mapObj)
	subMapConvertToStrcut(tempStruct, isRecursion)
	for _, key := range mapObjV.MapKeys() {
		fieldV := tempStruct.FieldByName(key.String())
		if fieldV.IsValid() && fieldV.CanSet() && fieldV.Type() == reflect.ValueOf(mapObjV.MapIndex(key).Interface()).Type() {
			fieldV.Set(reflect.ValueOf(mapObjV.MapIndex(key).Interface()))
		}
	}
	if isPointer {
		reflect.ValueOf(structObj).Elem().Set(tempStruct)
	}
	return tempStruct.Addr().Interface(), nil
}

func subMapConvertToStrcut(tempStruct reflect.Value, isRecursion bool) {
	tempStruct = reflect.Indirect(tempStruct)
	for i := 0; i < tempStruct.NumField(); i++ {
		if tempStruct.Field(i).Type().Kind() == reflect.Ptr {
			if !tempStruct.Field(i).CanSet() {
				continue
			}
			tempStruct.Field(i).Set(reflect.New(tempStruct.Field(i).Type().Elem()))
			if tempStruct.Field(i).Type().Elem().Kind() == reflect.Struct {
				if isRecursion {
					subMapConvertToStrcut(tempStruct.Field(i), true)
				}
			}
		}
	}
}

func DeJsonMappingObj(obj interface{}, tagField string, isCaseSensitive bool, data map[string]interface{}) (err error) {
	if InterfaceIsNil(obj) {
		return errors.New("obj is null")
	}
	if reflect.ValueOf(obj).Kind() != reflect.Ptr {
		return errors.New("Only Ptr Struct type is allowed")
	}
	objV := reflect.Indirect(reflect.ValueOf(obj))
	if objV.Kind() != reflect.Struct {
		return errors.New("Only struct type is allowed")
	}
	if tagField == "" {
		tagField = "json"
	}
	tagMappingField, err := objMapping(obj, tagField, isCaseSensitive)
	if err != nil {
		return err
	}
	data, _ = GetStrFieldValueWithCaseCheck(data, isCaseSensitive)
	for dataKey, idataValue := range data {
		fieldV, isExist := tagMappingField[dataKey]
		if isExist {
			err := subDeJsonMapping(fieldV, tagField, isCaseSensitive, idataValue)
			if err != nil && err != nilValueErr {
				return err
			}
		}
	}
	return nil
}

func objMapping(objSt interface{}, tagField string, isCaseSensitive bool) (map[string]reflect.Value, error) {
	if InterfaceIsNil(objSt) {
		return nil, errors.New("null obj is not allowed")
	}
	mapping := map[string]reflect.Value{}
	objV := reflect.Indirect(reflect.ValueOf(objSt))
	if objV.Kind() != reflect.Struct {
		return nil, errors.New("objSt is not struct")
	}
	for i := 0; i < objV.NumField(); i++ {
		fieldTag, isExist := objV.Type().Field(i).Tag.Lookup(tagField)
		if isExist {
			if !isCaseSensitive {
				mapping[strings.ToLower(fieldTag)] = objV.Field(i)
				continue
			}
			mapping[fieldTag] = objV.Field(i)
			continue
		}
		mapping[strings.ToLower(objV.Type().Field(i).Name)] = objV.Field(i)
	}
	return mapping, nil
}

func TagMappingStFieldName(tag string, obj interface{}) (map[string]string, error) {
	objT := reflect.ValueOf(obj).Type()
	result := map[string]string{}
	if objT.Kind() == reflect.Ptr {
		if objT.Elem().Kind() != reflect.Struct {
			return result, fmt.Errorf("obj should be struct or pointer to struct")
		}
		objT = objT.Elem()
	}
	if objT.Kind() != reflect.Struct {
		return result, fmt.Errorf("obj should be struct or pointer to struct")
	}
	for i := 0; i < objT.NumField(); i++ {
		tagValue, isExist := objT.Field(i).Tag.Lookup(tag)
		if isExist {
			result[tagValue] = objT.Field(i).Name
		}
	}
	return result, nil
}

func StFieldNameMappingTag(tag string, obj interface{}) (map[string]string, error) {
	objT := reflect.TypeOf(obj)
	result := map[string]string{}
	if objT.Kind() == reflect.Ptr {
		if objT.Elem().Kind() != reflect.Struct {
			return result, fmt.Errorf("obj should be struct or pointer to struct")
		}
		objT = objT.Elem()
	}
	if objT.Kind() != reflect.Struct {
		return result, fmt.Errorf("obj should be struct or pointer to struct")
	}
	for i := 0; i < objT.NumField(); i++ {
		tagValue, isExist := objT.Field(i).Tag.Lookup(tag)
		if isExist {
			result[objT.Field(i).Name] = tagValue
			continue
		}
		result[objT.Field(i).Name] = objT.Field(i).Name
	}
	return result, nil
}

func FieldValueToTagValue(stObj interface{}, tag string, isExeAnnoymous bool, fields ...string) (map[string]interface{}, error) {
	result := map[string]interface{}{}
	if InterfaceIsNil(stObj) {
		return result, fmt.Errorf("stObj is null")
	}
	stObjMap1, err := GetStrFieldValue(stObj, fields...)
	if err != nil {
		return result, err
	}
	if isExeAnnoymous {
		var e error
		stObjMap2 := map[string]interface{}{}
		annoymous := GetAnnoymousFileds(stObj)
		for k, v := range stObjMap1 {
			if _, ok := annoymous[k]; ok {
				vv, _ := FieldValueToTagValue(v, tag, isExeAnnoymous)
				stObjMap2, e = MergeStrKeyMap(vv, stObjMap2)
				if e != nil {
					return result, nil
				}
				continue
			}
			stObjMap2, _ = MergeStrKeyMap(map[string]interface{}{k: v}, stObjMap2)
		}
		stObjMap1 = stObjMap2
	}
	fieldMappingTag, err2 := StFieldNameMappingTag(tag, stObj)
	if err2 != nil {
		return result, err2
	}
	for fieldName, fieldValue := range stObjMap1 {
		if fieldMappingTag[fieldName] != "" {
			if tag == "json" && fieldMappingTag[fieldName] == "-" {
				continue
			}
			key := strings.Split(fieldMappingTag[fieldName], ",")[0]
			result[key] = fieldValue
			continue
		}
		if isExeAnnoymous {
			result[fieldName] = fieldValue
		}
	}
	return result, nil
}

func GetAnnoymousFileds(stObj interface{}) map[string]bool {
	result := map[string]bool{}
	if InterfaceIsNil(stObj) || !IsStruct(stObj) {
		return result
	}
	objV := reflect.Indirect(reflect.ValueOf(stObj))
	for i := 0; i < objV.NumField(); i++ {
		if objV.Type().Field(i).Anonymous {
			result[objV.Type().Field(i).Name] = true
		}
	}
	return result
}

func ArrayFieldValueToTagValue(arraytStObj interface{}, tag string) ([]map[string]interface{}, error) {
	result := []map[string]interface{}{}
	if InterfaceIsNil(arraytStObj) {
		return result, fmt.Errorf("stObj is null")
	}
	arraytStObjV := reflect.Indirect(reflect.ValueOf(arraytStObj))
	if !array_kit.IsArray(arraytStObj) || !IsStructElement(arraytStObj) {
		return result, fmt.Errorf("arrayStObj should be array of struct")
	}
	for i := 0; i < arraytStObjV.Len(); i++ {
		temp, err := FieldValueToTagValue(arraytStObjV.Index(i).Interface(), tag, false)
		if err == nil {
			result = append(result, temp)
			continue
		}
		return result, err
	}
	return result, nil
}

func GetObjTypeName(obj interface{}, isIgnorePointer bool) string {
	objT := reflect.TypeOf(obj)
	if objT.Kind() == reflect.Ptr && isIgnorePointer {
		objT = objT.Elem()
	}
	return objT.String()
}

type nilValueErrT string

const nilValueErr nilValueErrT = "NilValueError"

func (e nilValueErrT) Error() string {
	return string(nilValueErr)
}

func subDeJsonMapping(fiedldV reflect.Value, tagField string, isCaseSensitive bool, ifieldValue interface{}) error {
	if InterfaceIsNil(ifieldValue) {
		return nilValueErr
	}
	if !fiedldV.CanSet() {
		return errors.New("field can not be setted")
	}
	switch fiedldV.Kind() {
	case reflect.Interface:
		fiedldV.Set(reflect.ValueOf(ifieldValue))
	case reflect.String:
		if _, isOk := ifieldValue.(string); !isOk {
			return errors.New("convertion exception")
		}
		fiedldV.SetString(ifieldValue.(string))
	case reflect.Bool:
		if _, isOk := ifieldValue.(bool); !isOk {
			return errors.New("convertion exception")
		}
		fiedldV.SetBool(ifieldValue.(bool))
	case reflect.Float32, reflect.Float64:
		if _, isOk := ifieldValue.(float64); !isOk {
			return errors.New("convertion exception")
		}
		fiedldV.SetFloat(ifieldValue.(float64))
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if _, isOk := ifieldValue.(float64); !isOk {
			return errors.New("convertion exception")
		}
		fiedldV.SetInt(int64(ifieldValue.(float64)))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if _, isOk := ifieldValue.(float64); !isOk {
			return errors.New("convertion exception")
		}
		fiedldV.SetUint(uint64(ifieldValue.(float64)))
	case reflect.Ptr:
		fiedldVElement := fiedldV.Elem()
		if !fiedldVElement.CanSet() {
			fiedldVElement = reflect.New(fiedldV.Type().Elem()).Elem()
		}
		err := subDeJsonMapping(fiedldVElement, tagField, isCaseSensitive, ifieldValue)
		if err != nil {
			return err
		}
		fiedldV.Set(fiedldVElement.Addr())
	case reflect.Struct:
		newFieldSt := reflect.New(fiedldV.Type()).Elem()
		fieldValue, isOk := ifieldValue.(map[string]interface{})
		if !isOk {
			return errors.New("convertion exception")
		}
		DeJsonMappingObj(newFieldSt.Addr().Interface(), tagField, isCaseSensitive, fieldValue)
		fiedldV.Set(newFieldSt)
	case reflect.Slice:
		fieldValueSlice, isOk := ifieldValue.([]interface{})
		if !isOk {
			return errors.New("convertion exception")
		}
		fidldSlice := reflect.MakeSlice(fiedldV.Type(), 0, len(fieldValueSlice))
		fiedldV.Set(fidldSlice)
		for _, oneFieldValue := range fieldValueSlice {
			oneElement := reflect.New(fiedldV.Type().Elem()).Elem()
			err := subDeJsonMapping(oneElement, tagField, isCaseSensitive, oneFieldValue)
			if err == nil {
				fiedldV.Set(reflect.Append(fiedldV, oneElement))
				continue
			}
			return err
		}
	case reflect.Map:
		fieldValue, isOk := ifieldValue.(map[string]interface{})
		if !isOk {
			return errors.New("convertion exception")
		}
		if fiedldV.Type().Key().Kind() != reflect.String {
			return errors.New("field type exception")
		}
		newMap := reflect.MakeMap(fiedldV.Type())
		for fieldKey, fieldValue := range fieldValue {
			oneMapValue := reflect.New(fiedldV.Type().Elem()).Elem()
			err := subDeJsonMapping(oneMapValue, tagField, isCaseSensitive, fieldValue)
			if err == nil {
				newMap.SetMapIndex(reflect.ValueOf(fieldKey), oneMapValue)
				continue
			}
			return err
		}
		fiedldV.Set(newMap)
	default:
		return errors.New("field type is not supported")
	}
	return nil
}

func IsStructElement(obj interface{}) bool {
	if InterfaceIsNil(obj) {
		return false
	}
	objV := reflect.Indirect(reflect.ValueOf(obj))
	if !(objV.Kind() == reflect.Slice || objV.Kind() == reflect.Array) {
		return false
	}
	elementkind := objV.Type().Elem().Kind()
	switch elementkind {
	case reflect.Struct:
		return true
	case reflect.Ptr:
		if objV.Type().Elem().Elem().Kind() == reflect.Struct {
			return true
		}
	case reflect.Interface:
		if objV.Len() > 0 && reflect.ValueOf(objV.Index(0).Interface()).Kind() == reflect.Struct {
			return true
		}
	}
	return false
}

func ValidationFilterIdCard(idCard string) bool {
	switch utf8.RuneCountInString(idCard) {
	case 18:
		return idCardCheckSum18(idCard)
	case 15:
		return idCardCheckSum18(idCard15To18(idCard))
	default:
		return false
	}
}

func idCard15To18(idCard string) string {
	if utf8.RuneCountInString(idCard) != 15 {
		return ""
	}
	//如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
	if idExist, _ := array_kit.IsElementInArray(idCard[12:15], []string{"996", "997", "998", "999"}); idExist {
		idCard = idCard[0:6] + "18" + idCard[6:15]
	} else {
		idCard = idCard[0:6] + "19" + idCard[6:15]
	}
	return idCard + idCardVerifyNumber(idCard)
}

func idCardCheckSum18(idCard string) bool {
	if utf8.RuneCountInString(idCard) != 18 {
		return false
	}
	if idCardVerifyNumber(idCard[0:17]) != strings.ToUpper(idCard[17:18]) {
		return false
	}
	return true
}

func idCardVerifyNumber(idCardBase string) string {
	if utf8.RuneCountInString(idCardBase) != 17 {
		return ""
	}
	//加权因子
	factor := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
	//校验码对应值
	verifyNumberList := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
	checkNum := 0
	for i := 0; i < utf8.RuneCountInString(idCardBase); i++ {
		checkNum += (StringToInt(idCardBase[i:i+1]) * factor[i])
	}
	mod := checkNum % 11
	return verifyNumberList[mod]
}

func MergeMap(map1 interface{}, map2 interface{}) (map[interface{}]interface{}, error) {
	map1V := reflect.Indirect(reflect.ValueOf(map1))
	map2V := reflect.Indirect(reflect.ValueOf(map2))
	switch {
	case map1V.Kind() == reflect.Map && (map2V.Kind() != reflect.Map || InterfaceIsNil(map2)):
		return subMergeMap(map1V), nil
	case (map1V.Kind() != reflect.Map || InterfaceIsNil(map1)) && map2V.Kind() == reflect.Map:
		return subMergeMap(map2V), nil
	case (map1V.Kind() != reflect.Map && map2V.Kind() != reflect.Map) || (InterfaceIsNil(map1) || InterfaceIsNil(map2)):
		return nil, errors.New("both of to be merging type should be map")
	}
	if map1V.Type().Key() != map2V.Type().Key() || map1V.Type().Elem() != map2V.Type().Elem() {
		return nil, errors.New("both of to be merging obj should be same type")
	}
	rangeMapV1 := map1V.MapRange()
	for rangeMapV1.Next() {
		map2V.SetMapIndex(rangeMapV1.Key(), rangeMapV1.Value())
	}
	return subMergeMap(map2V), nil
}

func subMergeMap(mapV reflect.Value) map[interface{}]interface{} {
	rangMap := mapV.MapRange()
	result := map[interface{}]interface{}{}
	for rangMap.Next() {
		result[rangMap.Key().Interface()] = rangMap.Value().Interface()
	}
	return result
}

func MergeStrKeyMap(map1 interface{}, map2 interface{}) (map[string]interface{}, error) {
	temp, err := MergeMap(map1, map2)
	if err == nil {
		return GetStrFieldValue(temp)
	}
	return nil, err
}

func GetMapStrKeys(mapObj interface{}) ([]string, error) {
	if InterfaceIsNil(mapObj) {
		return []string{}, nil
	}
	objV := reflect.Indirect(reflect.ValueOf(mapObj))
	if objV.Kind() != reflect.Map {
		return []string{}, errors.New("obj is not map type")
	}
	keysMap := make([]string, 0, len(objV.MapKeys()))
	for _, keyV := range objV.MapKeys() {
		keysMap = append(keysMap, keyV.String())
	}
	return keysMap, nil
}

func GetMapKeys(mapObj interface{}) ([]interface{}, error) {
	keysMap := []interface{}{}
	if InterfaceIsNil(mapObj) {
		return keysMap, nil
	}
	objV := reflect.Indirect(reflect.ValueOf(mapObj))
	if objV.Kind() != reflect.Map {
		return nil, errors.New("obj is not map type")
	}
	for _, keyV := range objV.MapKeys() {
		keysMap = append(keysMap, keyV.Interface())
	}
	return keysMap, nil
}

func GetMapValues(mapObj interface{}) ([]interface{}, error) {
	valuesMap := []interface{}{}
	if InterfaceIsNil(mapObj) {
		return valuesMap, nil
	}
	objV := reflect.Indirect(reflect.ValueOf(mapObj))
	if objV.Kind() != reflect.Map {
		return nil, errors.New("obj is not map type")
	}
	for _, keyV := range objV.MapKeys() {
		valuesMap = append(valuesMap, objV.MapIndex(keyV).Interface())
	}
	return valuesMap, nil
}

func IsSpecificKind(obj interface{}, targetKind reflect.Kind) bool {
	if reflect.ValueOf(obj).Kind() == targetKind {
		return true
	}
	return false
}

func IsSpecificType(obj interface{}, targeType string) bool {
	objV := reflect.ValueOf(obj)
	if !objV.IsValid() {
		return false
	}
	if objV.Type().String() == targeType {
		return true
	}
	return false
}

func StructFields(titlesSt interface{}) ([]string, error) {
	objV := reflect.ValueOf(titlesSt)
	if !objV.IsValid() {
		return nil, fmt.Errorf("null is not be allowed")
	}
	objT := objV.Type()
	if objT.Kind() == reflect.Ptr {
		objT = objT.Elem()
	}
	if objT.Kind() != reflect.Struct {
		return nil, fmt.Errorf("only struct or pointer to struct is allowed")
	}
	fields := []string{}
	for i := 0; i < objT.NumField(); i++ {
		fields = append(fields, objT.Field(i).Name)
	}
	return fields, nil
}

func GenerateQueryStr(keyValue map[string]interface{}) string {
	if keyValue == nil || len(keyValue) == 0 {
		return ""
	}
	str := ""
	for key, value := range keyValue {
		oneKeyValueStr := key + "=" + fmt.Sprintf("%s", value)
		switch str {
		case "":
			str = "?" + oneKeyValueStr
		default:
			str += "&" + oneKeyValueStr
		}
	}
	return str
}

func ArrayMapPaging(arrayMapObj interface{}, pageIndex, eachPageRows int) (interface{}, error) {
	if InterfaceIsNil(arrayMapObj) {
		return nil, fmt.Errorf("arrayMapObj is null")
	}
	objV := reflect.Indirect(reflect.ValueOf(arrayMapObj))
	if (objV.Kind() != reflect.Slice && objV.Kind() != reflect.Array) || (objV.Type().Elem().Kind() != reflect.Map) {
		return nil, fmt.Errorf("arrayMapObj should be slice or arrray type,with map type element")
	}
	if pageIndex < 1 {
		pageIndex = 1
	}
	if eachPageRows < 1 {
		eachPageRows = 1
	}
	resultV := reflect.MakeSlice(objV.Type(), 0, eachPageRows)
	targetRows := pageIndex * eachPageRows
	skipRows := (pageIndex - 1) * eachPageRows
	for i := 0; i < objV.Len(); i++ {
		if i+1 > skipRows && i+1 <= targetRows {
			resultV = reflect.Append(resultV, objV.Index(i))
		}
	}
	return resultV.Interface(), nil
}

func IsStruct(obj interface{}) bool {
	if !reflect.ValueOf(obj).IsValid() {
		return false
	}
	switch reflect.TypeOf(obj).Kind() {
	case reflect.Struct:
		return true
	default:
		return false
	case reflect.Ptr:
		return reflect.TypeOf(obj).Elem().Kind() == reflect.Struct
	}
}

func GetObjMethods(st interface{}) (map[string]reflect.Value, error) { //key:method name value:method
	objV := reflect.ValueOf(st)
	if !objV.IsValid() || (IsReferenceType(objV) && objV.IsNil()) {
		return nil, errors.New("null is not allowed")
	}
	if objV.Kind() == reflect.Interface {
		return nil, errors.New("interface couldn't be method receiver")
	}
	objT := objV.Type()
	result := make(map[string]reflect.Value, 0)
	for i := 0; i < objV.NumMethod(); i++ {
		result[objT.Method(i).Name] = objV.Method(i)
	}
	return result, nil
}

//!!!!! return original value if exception !!!! if obj is map,and key of map is string
func ConvertTypeToStr(obj interface{}, targetType_ interface{}, tagOfStructField string, isExeAnnoymous bool) interface{} {
	if InterfaceIsNil(obj) || InterfaceIsNil(targetType_) {
		panic("obj or targetType is nil")
	}
	targetType := reflect.ValueOf(targetType_).Type()
	result := map[string]interface{}{}
	objV := reflect.Indirect(reflect.ValueOf(obj))
	if reflect.ValueOf(objV.Interface()).Type() == targetType {
		return fmt.Sprintf("%v", objV.Interface())
	}
	switch objV.Kind() {
	default:
		return obj
	case reflect.Array, reflect.Slice:
		temp := []interface{}{}
		for i := 0; i < objV.Len(); i++ {
			if objV.Index(i).CanInterface() {
				temp = append(temp, ConvertTypeToStr(objV.Index(i).Interface(), targetType_, tagOfStructField, isExeAnnoymous))
			}
		}
		return temp
	case reflect.Map:
		newObjMap := map[string]interface{}{}
		if objV.Type().Key().Kind() != reflect.String {
			keys := objV.MapKeys()
			for i := 0; i < len(keys); i++ {
				if keys[i].CanInterface() && objV.MapIndex(keys[i]).CanInterface() {
					newObjMap[fmt.Sprintf("%v", keys[i].Interface())] = objV.MapIndex(keys[i]).Interface()
				}
			}
			return ConvertTypeToStr(newObjMap, targetType_, tagOfStructField, isExeAnnoymous)
		}
		keys := objV.MapKeys()
		for i := 0; i < len(keys); i++ {
			ivalueV := objV.MapIndex(keys[i])
			if !ivalueV.IsValid() && ivalueV.IsZero() {
				result[keys[i].String()] = nil
				continue
			}
			if ivalueV.Type().Kind() == reflect.Ptr && (!ivalueV.IsValid() || ivalueV.IsZero()) {
				result[keys[i].String()] = nil
				continue
			}
			if !ivalueV.CanInterface() {
				continue
			}
			if InterfaceIsNil(ivalueV.Interface()) {
				result[keys[i].String()] = nil
				continue
			}
			ivalue := reflect.Indirect(ivalueV).Interface()
			if reflect.ValueOf(ivalueV.Interface()).Type() == targetType {
				result[keys[i].String()] = fmt.Sprintf("%v", ivalue)
				continue
			}
			if reflect.Indirect(reflect.ValueOf(ivalueV.Interface())).Type().Kind() == reflect.Struct {
				result[keys[i].String()] = ConvertTypeToStr(ivalue, targetType_, tagOfStructField, isExeAnnoymous)
				continue
			}
			if reflect.Indirect(reflect.ValueOf(ivalueV.Interface())).Type().Kind() == reflect.Map {
				result[keys[i].String()] = ConvertTypeToStr(ivalue, targetType_, tagOfStructField, isExeAnnoymous)
				continue
			}
			if reflect.Indirect(reflect.ValueOf(ivalueV.Interface())).Type().Kind() == reflect.Slice ||
				reflect.Indirect(reflect.ValueOf(ivalueV.Interface())).Type().Kind() == reflect.Array {
				iarray := reflect.Indirect(reflect.ValueOf(ivalueV.Interface()))
				temp := []interface{}{}
				for i := 0; i < iarray.Len(); i++ {
					if iarray.Index(i).CanInterface() {
						temp = append(temp, ConvertTypeToStr(iarray.Index(i).Interface(), targetType_, tagOfStructField, isExeAnnoymous))
					}
				}
				result[keys[i].String()] = temp
				continue
			}
			result[keys[i].String()] = ivalue
		}
		return result
	case reflect.Struct:
		temp, err := FieldValueToTagValue(obj, tagOfStructField, isExeAnnoymous)
		if err == nil {
			return ConvertTypeToStr(temp, targetType_, tagOfStructField, isExeAnnoymous)
		}
		return result
	}
}

func GetParValFromUrlString(urlStr string) (map[string]string, error) {
	//查找字符串的位置
	questionIndex := strings.Index(urlStr, "?")
	//判断是否存在/符号
	cutIndex := strings.Index(urlStr, "/")
	//打散成数组
	rs := []rune(urlStr)
	//用于存储请求的地址切割
	requestSlice := make([]string, 0, 0)
	//用于存储请求的参数字典
	parameterDict := make(map[string]string)
	//请求地址
	requsetStr := ""
	//参数地址
	parameterStr := ""
	//判断是否存在 ?
	if questionIndex != -1 {
		//判断url的长度
		parameterStr = string(rs[questionIndex+1 : utf8.RuneCountInString(urlStr)])
		requsetStr = string(rs[0:questionIndex])
		//参数数组
		parameterArray := strings.Split(parameterStr, "&")
		//生成参数字典
		for i := 0; i < len(parameterArray); i++ {
			str := parameterArray[i]
			if len(str) > 0 {
				tem := strings.Split(str, "=")
				if len(tem) > 0 && len(tem) == 1 {
					parameterDict[tem[0]] = ""
				} else if len(tem) > 1 {
					parameterDict[tem[0]] = tem[1]
				}
			}
		}
	} else {
		requsetStr = urlStr
	}

	//判断是否存在 /
	if cutIndex == -1 {
		requestSlice = append(requestSlice, requsetStr)
	} else {
		//按 / 切割
		requestArray := strings.Split(requsetStr, "/")
		for i := 0; i < len(requestArray); i++ {
			//判断第一个字符
			if i == 0 {
				//判断第一个字符串是否为空
				if len(requestArray[i]) != 0 {
					requestSlice = append(requestSlice, requestArray[i])
				}
			} else {
				requestSlice = append(requestSlice, requestArray[i])
			}
		}

	}
	return parameterDict, nil
}

func BuildCaseWhenSQL(tableName string, setName string, caseName string, builderMap map[string]string) (sql string) {

	inStr := ""
	sql = ""
	prefix := "UPDATE " + tableName + " SET " + setName + " = CASE " + caseName
	for index, item := range builderMap {
		inStr = inStr + "'" + index + "'" + ","
		sql = sql + " WHEN " + "'" + index + "'" + " THEN " + "'" + item + "'"
	}
	inStr = "(" + strings.TrimRight(inStr, ",") + ")"
	suffix := " END " + "WHERE " + caseName + " IN " + inStr

	sql = prefix + sql + suffix
	return
}

func BuildCaseWhenSQL2(tableName string, setName string, caseName string, builderMap map[string]interface{}) (sql string) {

	inStr := ""
	sql = ""
	prefix := "UPDATE " + tableName + " SET " + setName + " = CASE " + caseName
	for index, item := range builderMap {
		inStr = inStr + "'" + index + "'" + ","
		switch reflect.TypeOf(item).Kind() {
		case reflect.String:
			sql = sql + " WHEN " + "'" + index + "'" + " THEN " + "'" + item.(string) + "'"
		default:
			sql = sql + " WHEN " + "'" + index + "'" + " THEN " + fmt.Sprintf("%v", item)
		}

	}
	inStr = "(" + strings.TrimRight(inStr, ",") + ")"
	suffix := " END " + "WHERE " + caseName + " IN " + inStr

	sql = prefix + sql + suffix
	fmt.Printf("%s", sql)
	return
}

func IsNum(s string) bool {
	_, err := strconv.ParseFloat(s, 64)
	return err == nil
}
